﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO.IsolatedStorage;
using System.IO;

namespace AndersLiu.CnblogsIng
{
    public partial class MainWindow : Form
    {
        delegate string FetchMessageDelegate();
        delegate void PushMessageDelegate(string message);

        const string UserDataFileName = "userdata";
        static readonly Encoding UserDataEncoding = Encoding.UTF8;

        Random _rand = new Random();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            notifyIcon.Text = this.Text;

            LoadUserData();
        }

        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            SaveUserData();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                IngMobileClient.Send(txtVerifyCode.Text, txtContent.Text);

                MessageBox.Show("Message sent.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void notifyIcon_Click(object sender, EventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
        }

        private void MainWindow_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
                this.Visible = false;
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            var dlg = new AddMessageDialog();
            if (dlg.ShowDialog() != DialogResult.OK)
                return;

            lock (lstQueue)
            {
                foreach (var msg in dlg.Messages)
                {
                    if (msg != null && msg.Length > 0 && msg.Length < 150)
                        lstQueue.Items.Add(msg);
                }
            }
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            lock (lstQueue)
            {
                while (lstQueue.SelectedItems.Count > 0)
                    lstQueue.Items.Remove(lstQueue.SelectedItems[0]);
            }
        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            ChangeOptionsStauts(false);
            this.timer.Interval = (int)numInterval.Value * 60 * 1000;
            this.timer.Start();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            this.timer.Stop();
            ChangeOptionsStauts(true);
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            var msg = FetchMessage();

            if (msg == null)
            {
                btnStop.PerformClick();
                return;
            }

            lblStatus.Text = string.Format("Sending: " + msg);
            try
            {
                IngMobileClient.Send(txtVerifyCode.Text, msg);
            }
            catch
            {
                PushMessage(msg);
            }
            lblStatus.Text = "Ready";
        }

        string FetchMessage()
		{
			lock (lstQueue)
			{
				if (lstQueue.Items.Count == 0)
					return null;

				//var i = _rand.Next(0, lstQueue.Items.Count);
                var i = 0;
				var msg = lstQueue.Items[i].ToString();
				lstQueue.Items.RemoveAt(i);
				return msg;
			}
		}

        void PushMessage(string message)
        {
            lock (lstQueue)
            {
                lstQueue.Items.Add(message);
            }
        }

        void ChangeOptionsStauts(bool enabled)
        {
            btnPlay.Enabled = enabled;
            btnStop.Enabled = !enabled;
            numInterval.Enabled = enabled;
        }

        void LoadUserData()
        {
            try
            {
                var store = IsolatedStorageFile.GetUserStoreForAssembly();
                using (var stream = new IsolatedStorageFileStream(UserDataFileName,
                    FileMode.OpenOrCreate, FileAccess.Read, FileShare.None, store))
                {
                    using (var reader = new StreamReader(stream, UserDataEncoding))
                    {
                        txtVerifyCode.Text = reader.ReadLine();
                        numInterval.Value = int.Parse(reader.ReadLine());

                        lock (lstQueue)
                        {
                            var line = reader.ReadLine();
                            while (line != null)
                            {
                                lstQueue.Items.Add(line);
                                line = reader.ReadLine();
                            }
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        void SaveUserData()
        {
            try
            {
                var store = IsolatedStorageFile.GetUserStoreForAssembly();
                store.DeleteFile(UserDataFileName);
                using (var stream = new IsolatedStorageFileStream(UserDataFileName,
                    FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, store))
                {
                    using (var writer = new StreamWriter(stream, UserDataEncoding))
                    {
                        writer.WriteLine(txtVerifyCode.Text);
                        writer.WriteLine(numInterval.Value.ToString());

                        lock (lstQueue)
                        {
                            foreach (var item in lstQueue.Items)
                            {
                                writer.WriteLine(item);
                            }
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
    }
}
